#pragma once
#include <iostream>
#include <unordered_map>
#include <mutex>
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
typedef websocketpp::server<websocketpp::config::asio> websocket_server; // typedef方便在后续实例化对象
typedef websocket_server::message_ptr message_ptr;                       // 智能指针，它负责管理客户端发送到服务端的消息数据及其生命周期。


//管理游戏中在线用户的连接状态
class online_user_manager
{
public:
    online_user_manager()
    {
    }
    // 进入游戏大厅--游戏大厅连接建立成功后调用,方便后续可以向这些用户广播
    void enter_hall(uint64_t uid, const websocket_server::connection_ptr &conn)
    {
        // RAII管理锁资源，保证多线程安全
        std::unique_lock<std::mutex> lock(_mutex);
        _game_hall_user.insert(std::make_pair(uid, conn));
    }
    // 退出游戏大厅--游戏大厅连接断开后调用
    void exit_hall(uint64_t uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _game_hall_user.erase(uid);
    }

    // 进入游戏房间--游戏连接建立成功后调用
    void enter_room(uint64_t uid, const websocket_server::connection_ptr &conn)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _game_room_user.insert(std::make_pair(uid, conn));
    }

    // 退出游戏房间--游戏连接断开后调用
    void exit_room(uint64_t uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _game_room_user.erase(uid);
    }

    // 判断用户是否在游戏大厅
    bool in_hall(uint64_t uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _game_hall_user.find(uid);
        if (it == _game_hall_user.end())
        {
            return false;
        }
        return true;
    }

    // 判断用户是否在游戏房间
    bool in_room(uint64_t uid)
    {
      std::unique_lock<std::mutex> lock(_mutex);
        auto it = _game_room_user.find(uid);
        if (it == _game_room_user.end())
        {
            return false;
        }
        
        // 检查连接是否仍然有效
        websocket_server::connection_ptr conn = it->second;
        if (conn.get() == nullptr)
        {
            return false;
        }
        
        // 检查连接是否已关闭
        if (conn->get_state() != websocketpp::session::state::open)
        {
            return false;
        }
        
        return true;
    }

    // 从游戏大厅中获取指定用户关联的socket连接
    websocket_server::connection_ptr get_conn_from_game_hall(uint64_t uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _game_hall_user.find(uid);
        if (it == _game_hall_user.end())
        {
            return nullptr;
        }
        return it->second;
    }

    // 从游戏房间中获取指定用户关联的socket连接
    websocket_server::connection_ptr get_conn_from_game_room(uint64_t uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _game_room_user.find(uid);
        if (it == _game_room_user.end())
        {
            return nullptr;
        }
        return it->second;
    }

private:
    std::unordered_map<uint64_t, websocket_server::connection_ptr> _game_hall_user; // 大厅用户的客户端连接管理
    std::unordered_map<uint64_t, websocket_server::connection_ptr> _game_room_user; // 房间用户的客户端连接管理
    std::mutex _mutex;
};